package ua.edu.nuos.jeetraining2012.cms.util.oauth;


import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.scribe.builder.api.DefaultApi20;
import org.scribe.exceptions.OAuthException;
import org.scribe.model.*;
import org.scribe.oauth.OAuth20ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class VKontakteServiceImpl extends OAuth20ServiceImpl {
    private final DefaultApi20 api;
    private final OAuthConfig config;
    private String userId;

    /**
     * Default constructor
     *
     * @param api    OAuth2.0 api information
     * @param config OAuth 2.0 configuration param object
     */
    public VKontakteServiceImpl(DefaultApi20 api, OAuthConfig config) {
        super(api, config);
        this.api = api;
        this.config = config;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Token getAccessToken(Token requestToken, Verifier verifier) {
        Logger log = LoggerFactory.getLogger(getClass());
        OAuthRequest request = getOauthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
        request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
        request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
        request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue());
        request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
        if (config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, config.getScope());
        Response response = request.send();
        log.debug("getAccessToken() response body {}", response.getBody());
        try {
            JSONParser parser = new JSONParser();
            JSONObject jo = (JSONObject) parser.parse(response.getBody());
            userId = jo.get("user_id").toString();
            log.debug("getAccessToken() user id {}", userId);
        } catch (Exception e) {
            log.debug("getAccessToken() response body: {} Exception message: {}", response.getBody(), e.getMessage());
            throw new OAuthException("No user_id supplied");
        }
        return api.getAccessTokenExtractor().extract(response.getBody());
    }

    /**
     * Constructs and return OAuthRequest Object
     */
    protected OAuthRequest getOauthRequest(Verb verb, String url) {
        return new OAuthRequest(verb, url);
    }

    public String getUserId() {
        return userId;
    }
}

